﻿///*
// * BitmapBlock
// * 
// * Copyright (c) Adam Sida, asida@centrum.cz
// * 
// * All rights reserved.
// */
//using System;
//using System.IO;
////using System.Drawing;
////using System.Drawing.Imaging;
//using System.Windows;
//using System.Windows.Media;
//using System.Windows.Media.Imaging;
//using Petra.Gis.Geometry.Image.Tiff;



//namespace Petra.Gis.Geometry.Image
//{

//  /// <summary>
//  /// represents small rectangular portion of larger bitmap that can always fit into memory
//  /// typical uncompressed size is aprox. 64kB, but can be any (no limit now)
//  /// objects can:
//  /// load data into existing bitmap
//  /// load data into new empty bitmap
//  /// extract data from existing bitmap into new bitmap
//  /// </summary>
//  public abstract class StreamBitmapBlock
//  {

//    public enum BitmapOperationType { ExtractDataIntoNew = 0, WorkOnExisting = 1 }

//    protected Int32Rect _bounds; //position of this image in destionation bitmap
//    protected BlockBitmapSource _parentBitmap; //parent object that owns this child
//    //protected PixelFormat _pixelFormat; // pixel format for output bitmap
//    protected BitmapSource _bitmap; //output bitmap
//    protected TiffMetadata _metadata; //metadata
//    protected int _index; //index of block in frame block diagram (single dimensional) 0 - N
//    //protected Rectangle _areaOfInterest; //??
//    protected TiffReader _tiffReader;

//    #region constructors

//    /// <summary>
//    /// basic constructor 
//    /// creates BitmapBlock from dimensions and pixelFormat only
//    /// </summary>
//    /// <param name="bounds">block position and size</param>
//    /// <param name="PixelFormat">format of pixel for this block</param>
//    public StreamBitmapBlock(BlockBitmapSource parentBitmap, Int32Rect bounds)
//    {
//      if (bounds == null)
//        throw new ArgumentException("null bounds or pixelFormat");

//      _parentBitmap = parentBitmap;
//      _bounds = bounds;
//      //_pixelFormat = pixelFormat;
//    }




//    ///// <summary>
//    ///// creates BitmapBlock from given recangle and TiffMetadata
//    ///// </summary>
//    ///// <param name="bounds"></param>
//    ///// <param name="meta"></param>
//    //protected StreamBitmapBlock(Int32Rect bounds, TiffMetadata metadata)
//    //{
//    //  if (bounds == null || metadata == null)
//    //    throw new ArgumentException("null bounds or TiffMetadata");

//    //  _bounds = bounds;
//    //  //_pixelFormat = getPixelFormatByMetadata(metadata);
//    //  _metadata = metadata;
//    //}




//    /// <summary>
//    /// creates BitmapBlock from existing bitmap
//    /// </summary>
//    /// <param name="sourceBmp"></param>
//    /// <param name="srcPos"></param>
//    public StreamBitmapBlock(BlockBitmapSource parentBitmap, BitmapSource sourceBmp, Int32Rect srcPos, BitmapOperationType oType)
//      : this(parentBitmap, srcPos)
//    {
//      if (srcPos.X < 0 || (srcPos.X + srcPos.Width) > sourceBmp.PixelWidth ||
//          srcPos.Y < 0 || (srcPos.Y + srcPos.Height) > sourceBmp.PixelHeight)
//        throw new ArgumentException("invalid areaOfInterest size, larger than bitmap");

//      if (oType == BitmapOperationType.WorkOnExisting)
//        _bitmap = sourceBmp;
//      else
//        //initialize(sourceBmp, srcPos);
//        _bitmap = new CroppedBitmap(sourceBmp, srcPos);

//      _bounds = srcPos;
//    }

//    #endregion constructors

//    #region public members



//    /// <summary>
//    /// this will load data from image into block
//    /// decompress if needed
//    /// convert color schema if needed
//    /// </summary>
//    public abstract void LoadData();
//    //public virtual void LoadData()
//    //{
//    //  //if bitmap created as empty initialize new
//    //  if (_bitmap == null)
//    //    initialize(_parentBitmap.Format);

//    //}



//    /// <summary>
//    /// represents position and size of current BitmapBlock in destination image
//    /// </summary>
//    public Int32Rect Bounds
//    {
//      get { return _bounds; }
//    }


//    public BitmapSource BitmapSource
//    {
//      get { return _bitmap; }
//    }

//    #endregion public members


//    /// <summary>
//    /// initializes this BitmapBlock with new empty bitmap
//    /// </summary>
//    protected virtual void initialize(PixelFormat pixFmt)
//    {
//      _bitmap = new RenderTargetBitmap(_bounds.Width, _bounds.Height, 600, 600, pixFmt);
//    }



//    ///// <summary>
//    ///// creates private copy of data from given bitmap
//    ///// </summary>
//    ///// <param name="sourceBmp">source bitmap to copy data from</param>
//    ///// <param name="aoi">area of interest in this bitmap</param>
//    //protected unsafe void initialize(Bitmap sourceBmp, Rectangle aoi)
//    //{
//    //  int pixelByteLen, rowByteLen;

//    //  _bitmap = new Bitmap(aoi.Width, aoi.Height, sourceBmp.PixelFormat);
//    //  BitmapData bdSrc = sourceBmp.LockBits(new Rectangle(0, 0, aoi.Width, aoi.Height), ImageLockMode.ReadOnly, sourceBmp.PixelFormat);
//    //  BitmapData bdDst = sourceBmp.LockBits(new Rectangle(0, 0, aoi.Width, aoi.Height), ImageLockMode.ReadOnly, sourceBmp.PixelFormat);

//    //  if((bdSrc.Stride % 8) != 0)
//    //    throw new ArgumentException("unsupported PixelFormat, stride must be modulo of 8");

//    //  pixelByteLen = getPixelByteSize(sourceBmp.PixelFormat);

//    //  rowByteLen = pixelByteLen * aoi.Width;
//    //  byte* srcBmpPtr = (byte*)bdSrc.Scan0;
//    //  byte* dstBmpPtr = (byte*)bdDst.Scan0;

//    //  // copy data per stride
//    //  int colPos = 1;  // one based
//    //  int rowPos = 0;  //zero based
//    //  while (rowPos < _bitmap.Height)
//    //  {
//    //    *dstBmpPtr++ = *srcBmpPtr++;
//    //    if (colPos++ == rowByteLen)
//    //    {
//    //      rowPos++;
//    //      colPos = 1;
//    //      srcBmpPtr += (bdSrc.Stride - rowByteLen);
//    //    }
//    //  }
//    //  sourceBmp.UnlockBits(bdSrc);
//    //  _bitmap.UnlockBits(bdDst);
//    //}



//    ///// <summary>
//    ///// determines pixel size from bitmap
//    ///// </summary>
//    ///// <param name="pxf"></param>
//    ///// <returns></returns>
//    //protected int getPixelByteSize(PixelFormat pxf)
//    //{

//    //  return pxf.BitsPerPixel;

//    //  int pixelSize;
//    //  switch (pxf)
//    //  {
//    //    case PixelFormats.Indexed8:
//    //      pixelSize = 1; //in bytes
//    //      break;
//    //    case PixelFormats.Gray16:
//    //    case PixelFormat.Format16bppGrayScale:
//    //    case PixelFormat.Format16bppRgb555:
//    //    case PixelFormat.Format16bppRgb565:
//    //      pixelSize = 2; //in bytes
//    //      break;
//    //    case PixelFormat.Format24bppRgb:
//    //      pixelSize = 3; //in bytes
//    //      break;
//    //    case PixelFormat.Format32bppArgb:
//    //    case PixelFormat.Format32bppPArgb:
//    //    case PixelFormat.Format32bppRgb:
//    //      pixelSize = 4; //in bytes
//    //      break;
//    //    case PixelFormat.Format48bppRgb:
//    //      pixelSize = 6; //in bytes
//    //      break;
//    //    default:
//    //      throw new ArgumentException("unsupported PixelFormat");
//    //  }
//    //  return pixelSize;
//    //}



//    /// <summary>
//    /// remaps tiff pixel definition onto windows PixelFormat
//    /// </summary>
//    /// <param name="mtdt"></param>
//    /// <returns></returns>
//    private PixelFormat getPixelFormatByMetadata(TiffMetadata mtdt)
//    {
//      PixelFormat pixFmt;
//      switch (mtdt.PhotometricInterpretation)
//      {
//        //case PhotometricType.UNKNOWN:
//        case PhotometricType.WHITE_IS_ZERO:
//        case PhotometricType.BLACK_IS_ZERO:
//          pixFmt = PixelFormats.BlackWhite;
//          break;
//        case PhotometricType.PALETTED:
//          pixFmt = PixelFormats.Indexed8;
//          break;
//        case PhotometricType.TRUECOLOR_RGB:
//        case PhotometricType.YCBCR:
//          pixFmt = PixelFormats.Bgr24;
//          break;
//        default:
//          throw new ArgumentException("unsupported photometric type, sorry");
//      }

//      return pixFmt;
//    }

//  }
//}
